package cn.edu.fzu.delivery.controller.customer;

import cn.edu.fzu.delivery.common.PageVO;
import cn.edu.fzu.delivery.common.Result;
import cn.edu.fzu.delivery.domain.entity.Courier;
import cn.edu.fzu.delivery.domain.entity.CourierDelivery;
import cn.edu.fzu.delivery.domain.entity.Customer;
import cn.edu.fzu.delivery.domain.entity.Logistics;
import cn.edu.fzu.delivery.domain.entity.SysUser;
import cn.edu.fzu.delivery.domain.enums.CourierStatusEnum;
import cn.edu.fzu.delivery.domain.enums.CourierTypeEnum;
import cn.edu.fzu.delivery.domain.enums.DeliveryStatusEnum;
import cn.edu.fzu.delivery.domain.enums.NetworkCourierStatusEnum;
import cn.edu.fzu.delivery.domain.enums.UrgencyEnum;
import cn.edu.fzu.delivery.exception.ServiceException;
import cn.edu.fzu.delivery.service.CourierDeliveryService;
import cn.edu.fzu.delivery.service.CourierService;
import cn.edu.fzu.delivery.session.SessionConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.oas.annotations.EnableOpenApi;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 顾客快递管理
 * 
 * @author fangxin
 * @date 2022/11/8
 */
@EnableOpenApi
@Api(tags = "顾客-快递管理")
@RestController
public class CustomerDeliveryController {

    private static final String    HOUR_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Resource
    private CourierService         courierService;

    @Resource
    private CourierDeliveryService courierDeliveryService;

    @ApiOperation(value = "获取顾客所有的寄件", httpMethod = "POST")
    @ApiImplicitParams({ @ApiImplicitParam(name = "courierIds", value = "快递单号，支持多个，英文逗号分隔"),
            @ApiImplicitParam(name = "type", value = "快递类型"), @ApiImplicitParam(name = "status", value = "快递状态"),
            @ApiImplicitParam(name = "urgency", value = "快递紧急程度"),
            @ApiImplicitParam(name = "startTime", value = "开始时间"), @ApiImplicitParam(name = "endTime", value = "结束时间"),
            @ApiImplicitParam(name = "pageNum", value = "分页参数：当前页，默认从1开始"),
            @ApiImplicitParam(name = "pageSize", value = "分页参数：每页展示数据的多少") })
    @PostMapping("/api/auth/customer/delivery/listSend")
    public Result listSend(String courierIds, CourierTypeEnum type, CourierStatusEnum status, UrgencyEnum urgency,
                           String startTime, String endTime, Integer pageNum, Integer pageSize,
                           HttpServletRequest request) {
        Customer customer = (Customer) request.getSession().getAttribute(SessionConstant.DELIVERY_ACCOUNT);

        List<Courier> list = courierService.listCustomerSend(customer.getPhone(),
                StringUtils.isBlank(courierIds) ? null : Arrays.asList(courierIds.split(",")), type, status, urgency,
                startTime, endTime);
        return new Result(PageVO.page(pageNum, pageSize, list));

    }


    @ApiOperation(value = "获取顾客所有的收件", httpMethod = "POST")
    @PostMapping("/api/auth/customer/delivery/listReceive")
    @ApiImplicitParams({ @ApiImplicitParam(name = "courierIds", value = "快递单号，支持多个，英文逗号分隔"),
            @ApiImplicitParam(name = "type", value = "快递类型"), @ApiImplicitParam(name = "status", value = "快递状态"),
            @ApiImplicitParam(name = "urgency", value = "快递紧急程度"),
            @ApiImplicitParam(name = "startTime", value = "开始时间"), @ApiImplicitParam(name = "endTime", value = "结束时间"),
            @ApiImplicitParam(name = "pageNum", value = "分页参数：当前页，默认从1开始"),
            @ApiImplicitParam(name = "pageSize", value = "分页参数：每页展示数据的多少") })
    public Result listReceive(String courierIds, CourierTypeEnum type, CourierStatusEnum status, UrgencyEnum urgency,
                              String startTime, String endTime, Integer pageNum, Integer pageSize,
                              HttpServletRequest request) {
        Customer customer = (Customer) request.getSession().getAttribute(SessionConstant.DELIVERY_ACCOUNT);
        List<Courier> list = courierService.listCustomerReceive(customer.getPhone(),
                StringUtils.isBlank(courierIds) ? null : Arrays.asList(courierIds.split(",")), type, status, urgency,
                startTime, endTime);
        return new Result(PageVO.page(pageNum, pageSize, list));
    }


    @ApiOperation(value = "寄快递", httpMethod = "POST", notes = "顾客填写了")
    @PostMapping("/api/auth/customer/delivery/send")
    @ApiImplicitParams({ @ApiImplicitParam(name = "sendAddressId", value = "寄件地址id，可选"),
            @ApiImplicitParam(name = "receiveAddressId", value = "收件地址id，可选"),
            @ApiImplicitParam(name = "sendNetworkId", value = "寄件网点，当寄件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "senderAddress", value = "寄件人详细地址,当寄件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "receiverName", value = "收件人姓名,当收件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "receiverPhone", value = "收件人手机号,当收件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "receiverEmail", value = "收件人邮箱,当收件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "receiveNetworkId", value = "收件网点,当收件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "receiverAddress", value = "收件人详细地址,当收件地址id为空时，必选，否则可选"),
            @ApiImplicitParam(name = "type", value = "快递类型", required = true),
            @ApiImplicitParam(name = "urgency", value = "紧急程度", required = true) })
    public Result send(Long sendAddressId, Long receiveAddressId, Long sendNetworkId, String senderAddress,
                       String receiverName, String receiverPhone, String receiverEmail, Long receiveNetworkId,
                       String receiverAddress, @RequestParam CourierTypeEnum type, @RequestParam UrgencyEnum urgency,
                       HttpServletRequest request) {
        HttpSession session = request.getSession();
        Customer customer = (Customer) session.getAttribute(SessionConstant.DELIVERY_ACCOUNT);
        String city = (String) session.getAttribute(SessionConstant.CITY);
        courierService.send(city, sendAddressId, receiveAddressId, customer, sendNetworkId, senderAddress, receiverName,
                receiverPhone, receiverEmail, receiveNetworkId, receiverAddress, type, urgency);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "查询快递单价", httpMethod = "GET")
    @ApiImplicitParams({ @ApiImplicitParam(name = "type", value = "0-书籍，1-衣物") })
    @GetMapping("/api/auth/customer/delivery/queryPrice")
    public Result queryPrice(CourierTypeEnum type) {
        return new Result(courierService.queryPrice(type));
    }


    @ApiOperation(value = "查快递（无需登录）", httpMethod = "GET")
    @RequestMapping("/api/customer/delivery/query")
    @ApiImplicitParams({ @ApiImplicitParam(name = "courierIds", value = "快递单号，支持多个，英文逗号分隔"),
            @ApiImplicitParam(name = "phone", value = "收件手机号") })
    public Result query(String courierIds, String phone) {
        if (StringUtils.isBlank(courierIds) && StringUtils.isBlank(phone)) {
            return new Result(null);
        }

        List<Courier> couriers = courierService.listCustomerReceive(phone,
                StringUtils.isBlank(courierIds) ? null : Arrays.asList(courierIds.split(",")), null, null, null, null,
                null);
        return new Result(couriers);
    }


    @ApiOperation(value = "查询快递详情", httpMethod = "GET")
    @GetMapping("/api/auth/customer/delivery/detail")
    public Result detail(String courierId) {
        return new Result(courierService.getByCourierId(courierId));
    }


    @ApiOperation(value = "查询快递的运输天数和路径", httpMethod = "GET")
    @GetMapping("/api/customer/delivery/getDeliveryPath")
    public Result getDayAndPath(String courierId) {
        return new Result(courierService.getDeliveryPath(courierId));
    }


    @ApiOperation("扫描收货（前端不要调用）")
    @GetMapping("/api/customer/delivery/receive")
    public ModelAndView QRCode(@RequestParam String courierId) {
        ModelAndView mav = new ModelAndView("QrCode");
        try {
            courierService.update(courierId, null, CourierStatusEnum.ARRIVED, null,
                    DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"), true);
        } catch (ServiceException e) {
            mav.addObject("error", e.getMessage());
        }
        return mav;
    }


    @ApiOperation(value = "快递催单(前端调用)", httpMethod = "GET")
    @GetMapping("/api/auth/customer/delivery/urge")
    public Result urge(String courierId) {
        courierService.urge(courierId);
        return Result.SUCCESS;
    }


    @ApiOperation(value = "快递催单(邮件使用，前端不用调用)", httpMethod = "GET")
    @GetMapping("/api/customer/delivery/urgeByEmail")
    public ModelAndView urgeByEmail(String courierId) {
        ModelAndView mav = new ModelAndView("email");
        Courier courier = courierService.getByCourierId(courierId);
        if (courier == null) {
            mav.addObject("error", "快递不存在");
            return mav;
        }
        List<String> logisticsList = new ArrayList<>();
        try {
            courierService.urge(courierId);
            //催单成功代表正处于派送中，则把收件地址拼接上
            logisticsList.add(courier.getReceiver().getAddress());
        } catch (ServiceException e) {
            if (courier.getStatus() == CourierStatusEnum.ARRIVED) {
                mav.addObject("error", "快递已签收");
            } else {
                mav.addObject("error", e.getMessage());
            }
        }
        if (courier.getStatus() == CourierStatusEnum.ARRIVED) {
            logisticsList.add("快递已签收:" + courier.getReceiver().getAddress() + "-"
                    + DateFormatUtils.format(courier.getEndTime(), HOUR_FORMAT));
        }
        if (courier.getStatus() == CourierStatusEnum.DELIVERY) {
            List<CourierDelivery> list = courierDeliveryService.list(null, courierId, DeliveryStatusEnum.DELIVERING,
                    null, null, null);
            if (CollectionUtils.isNotEmpty(list)) {
                SysUser deliveryMan = list.get(0).getDeliveryMan();
                logisticsList.add("快递员:" + deliveryMan.getName() + "正在给您派件，请耐心等待,联系电话：" + deliveryMan.getPhone());
            }
        }
        //拼接物流信息
        Logistics logistics = courier.getLogistics();
        while (logistics != null) {
            if (logistics.getStatus() == NetworkCourierStatusEnum.LEAVE) {
                logisticsList.add("已离开 " + logistics.getNetwork().getName()
                        + (StringUtils.isNotBlank(logistics.getNetwork().getAddress())
                                ? " ：" + logistics.getNetwork().getAddress()
                                : "")
                        + "  " + DateFormatUtils.format(logistics.getLeaveTime(), HOUR_FORMAT));
            }
            logisticsList.add("已到达 " + logistics.getNetwork().getName()
                    + (StringUtils.isNotBlank(logistics.getNetwork().getAddress())
                            ? " ：" + logistics.getNetwork().getAddress()
                            : "")
                    + "  " + DateFormatUtils.format(logistics.getCreateTime(), HOUR_FORMAT));
            logistics = logistics.getParent();
        }
        mav.addObject("logistics", logisticsList);
        return mav;
    }
}
